export class Node {
  constructor (element) {
    this.element = element
    this.next = null
  }
}

export class LinkedList {
  head = null
  length = 0

  // 向链表尾部添加一个新的项
  append (element) {
    const newNode = new Node(element)

    if (!this.head) {
      this.head = newNode
    } else {
      let current = this.head
      while (current.next) {
        current = current.next
      }

      current.next = newNode
    }

    this.length++
  }
  // 向链表的特定位置插入一个新的项
  insert (position, element) {
    if (position < 0 || position > this.length) return false

    const newNode = new Node(element)

    if (position === 0) {
      newNode.next = this.head
      this.head = newNode
    } else {
      let index = 0
      let current = this.head
      let previous = null
      while (index++ < position) {
        previous = current
        current = current.next
      }

      previous.next = newNode
      newNode.next = current
    }

    this.length++

    return true
  }
  // 获取对应位置的元素
  get (position) {
    if (position < 0 || position > this.length - 1) return null
    
    let index = 0
    let current = this.head
    while (index++ < position) {
      current = current.next
    }
    
    return current.element
  }
  // 返回元素在链表中的索引，如果链表中没有该元素则返回-1
  indexOf (element) {
    let index = 0
    let current = this.head

    while (current) {
      if (current.element === element) {
        return index
      }

      index++
      current = current.next
    }

    return -1
  }
  // 修改某个位置的元素
  update (position, element) {
    const result = this.removeAt(position)

    this.insert(position, element)

    return result
  }
  // 从链表的指定位置移除一项
  removeAt (position) {
    if (position < 0 || position > this.length - 1) return null

    let current = this.head
    let previous = null
    let index = 0

    if (position === 0) {
      this.head = current.next
    } else {
      while (index++ < position) {
        previous = current
        current =  current.next
      }
      previous.next = current.next
    }

    this.length--

    return current.element
  }
  // 从链表中移除一项
  remove (element) {
    const index = this.indexOf(element)

    if (index === -1) return null

    return this.removeAt(index)
  }
  // 如果链表中不包含任何元素，返回true，如果链表长度大于0则返回false
  isEmpty () {
    return this.length === 0
  }
  // 返回链表包含的元素个数，与数组的length属性类似
  size () {
    return this.length
  }
}